<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>UI Datepicker Tests</title>
<script type="text/javascript" src="jsUnitCore.js"></script>
<script type="text/javascript" src="../core/jquery.js"></script>
<script type="text/javascript" src="../core/ui.datepicker.js"></script>
<script type="text/javascript">
function setUpPage() {
	$('#dp').attachDatepicker({clearText: 'Erase'});
	$('#adj').attachDatepicker();
	$('#rem').attachDatepicker({showOn: 'both'});
	setUpPageStatus = "complete";
}

function testSetDefaults() {
	assertEquals('Invalid initial showOn', 'focus', $.datepicker._defaults.showOn);
	$.datepicker.setDefaults({showOn: 'both'});
	assertEquals('Invalid changed showOn', 'both', $.datepicker._defaults.showOn);
	$.datepicker.setDefaults({showOn: 'focus'});
}

function testRemove() {
	var rem = $('#rem');
	assertEquals('Missing ID', 2, rem[0]._calId);
	assertTrue('Missing wrapper', rem.parent('.datepicker_wrap').length > 0);
	assertTrue('Missing marker class', rem.is('.hasDatepicker'));
	rem.removeDatepicker();
	rem = $('#rem');
	assertUndefined('ID still there', rem[0]._calId);
	assertFalse('Wrapper still there', rem.parent('.datepicker_wrap').length > 0);
	assertFalse('Marker class still there', rem.is('.hasDatepicker'));
}

function testDisableEnable() {
	var dp = $('#dp');
	assertFalse('Control is disabled', dp.isDisabledDatepicker());
	$('#dp').disableDatepicker();
	assertTrue('Control is enabled by ID', dp.isDisabledDatepicker());
	$('#dp').enableDatepicker();
	assertFalse('Control is disabled by ID', dp.isDisabledDatepicker());
}

function testChange() {
	assertEquals('Invalid instance clearText', 'Erase',
		$.datepicker._inst[0]._settings.clearText);
	$('#dp').changeDatepicker({clearText: 'X1'});
	assertEquals('Invalid instance clearText', 'X1',
		$.datepicker._inst[0]._settings.clearText);
	$('#dp').changeDatepicker({clearText: 'X2'});
	assertEquals('Invalid instance clearText', 'X2',
		$.datepicker._inst[0]._settings.clearText);
	$('#dp:first').changeDatepicker({clearText: 'X3'});
	assertEquals('Invalid instance clearText', 'X3',
		$.datepicker._inst[0]._settings.clearText);
	$('#dp:first').changeDatepicker({clearText: null});
	assertNull('Invalid instance clearText', $.datepicker._inst[0]._settings.clearText);
	$('#dp').changeDatepicker({clearText: 'Erase'});
	assertEquals('Invalid instance clearText', 'Erase',
		$.datepicker._inst[0]._settings.clearText);
	$('#dp').changeDatepicker('clearText', 'X1');
	assertEquals('Invalid instance clearText', 'X1',
		$.datepicker._inst[0]._settings.clearText);
	$('#dp:first').changeDatepicker('clearText', null);
	assertNull('Invalid instance clearText', $.datepicker._inst[0]._settings.clearText);
	$('#dp').changeDatepicker('clearText', 'Erase');
	assertEquals('Invalid instance clearText', 'Erase',
		$.datepicker._inst[0]._settings.clearText);
}

function testSetGetDateFor() {
	var dp = $('#dp');
	assertNull('Invalid date set', dp.getDatepickerDate());
	var date = new Date(2001, 2 - 1, 3);
	dp.setDatepickerDate(date);
	assertEquals('Invalid date set/get by jQuery', date.toString(), 
		dp.getDatepickerDate().toString());
}

function testNoWeekends() {
	for (var d = 0; d < 28; d++) {
		assertArrayEquals('Weekend options invalid for ' + d + '/12/2007',
			[(d % 7) > 1, ''], $.datepicker.noWeekends(new Date(2007, 12 - 1, d + 1)));
    }
}

function testIso8601Week() {
	var weeks = [[new Date(2007, 12 - 1, 30), 52], [new Date(2007, 12 - 1, 31), 1],
		[new Date(2008, 1 - 1, 1), 1], [new Date(2008, 1 - 1, 6), 1],
		[new Date(2008, 1 - 1, 7), 2], [new Date(2008, 3 - 1, 24), 13],
		[new Date(2008, 3 - 1, 31), 14], [new Date(2008, 7 - 1, 10), 28],
		[new Date(2008, 12 - 1, 28), 52], [new Date(2008, 12 - 1, 29), 1],
		[new Date(2008, 12 - 1, 31), 1], [new Date(2009, 1 - 1, 1), 1],
		[new Date(2009, 12 - 1, 27), 52], [new Date(2009, 12 - 1, 28), 53],
		[new Date(2009, 12 - 1, 31), 53], [new Date(2010, 1 - 1, 1), 53],
		[new Date(2010, 1 - 1, 3), 53], [new Date(2010, 1 - 1, 4), 1]];
	for (var i = 0; i < weeks.length; i++) {
		assertEquals('Invalid ISO week for ' + weeks[i][0], weeks[i][1],
			$.datepicker.iso8601Week(weeks[i][0]));
	}
}

function testParseDate() {
	var date = new Date(2007, 6 - 1, 5);
	assertNull('Invalid parsed date - blank',
		$.datepicker.parseDate('dd/mm/yy', ''));
	assertDateEquals('Invalid parsed date - dd/mm/yy', date,
		$.datepicker.parseDate('dd/mm/yy', '05/06/2007'));
	assertDateEquals('Invalid parsed date - d/m/yy', date,
		$.datepicker.parseDate('d/m/yy', '5/6/2007'));
	assertDateEquals('Invalid parsed date - dd/mm/yy (2)', date,
		$.datepicker.parseDate('dd/mm/yy', '5/6/2007'));
	assertDateEquals('Invalid parsed date - d/m/yy (2)', date,
		$.datepicker.parseDate('d/m/yy', '05/06/2007'));
	assertDateEquals('Invalid parsed date - yy-mm-dd', date,
		$.datepicker.parseDate('yy-mm-dd', '2007-06-05'));
	assertDateEquals('Invalid parsed date - ddMyy', date,
		$.datepicker.parseDate('ddMyy', '05Jun2007'));
	assertDateEquals('Invalid parsed date - DD, MM d, yy', date,
		$.datepicker.parseDate('DD, MM d, yy', 'Tuesday, June 5, 2007'));
	assertDateEquals('Invalid parsed date - dd\'\'mm\'\'yy', date,
		$.datepicker.parseDate('dd\'\'mm\'\'yy', '05\'06\'2007'));
	assertDateEquals('Invalid parsed date - \'Day\' d of MM in the \'year\' yy', date,
		$.datepicker.parseDate('\'Day\' d of MM in the \'year\' yy',
		'Day 5 of June in the year 2007'));
	assertDateEquals('Invalid parsed date - D M dd yy', date,
		$.datepicker.parseDate('D M dd yy', date));
	// check short year
	assertDateEquals('Invalid parsed date - dd/mm/y (< cutoff)', date,
		$.datepicker.parseDate('dd/mm/y', '05/06/07', 10));
	assertDateEquals('Invalid parsed date - dd/mm/y (> cutoff)', new Date(1907, 6 - 1, 5),
		$.datepicker.parseDate('dd/mm/y', '05/06/07', 5));
	// other language
	assertDateEquals('Invalid parsed date - DddMyy', date,
		$.datepicker.parseDate('DddMyy', 'dth05msi2007', 10,
		['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
		['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
		['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
		'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
		['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
		'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']));
	assertDateEquals('Invalid parsed date - DD dd MM yy', date,
		$.datepicker.parseDate('DD dd MM yy', 'dthree 05 msix 2007', 10,
		['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
		['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
		['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
		'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
		['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
		'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']));
}

function testParseDateErrors() {
	try {
		$.datepicker.parseDate(null, '05/06/2007');
		fail('Parsed null format argument');
	}
	catch (e) {
		assertEquals('Unexpected error message - null format', 'Invalid arguments', e);
	}
	try {
		$.datepicker.parseDate('dd/mm/yy', null);
		fail('Parsed null value argument');
	}
	catch (e) {
		assertEquals('Unexpected error message - null value', 'Invalid arguments', e);
	}
	try {
		$.datepicker.parseDate('dd-mm-yy', '05/06/2007');
		fail('Parsed invalid format - dd-mm-yy');
	}
	catch (e) {
		assertEquals('Unexpected error message - 05/06/2007',
			'Unexpected literal at position 2', e);
	}
	try {
		$.datepicker.parseDate('dMyy', '05Jum2007');
		fail('Parsed invalid format - dMyy');
	}
	catch (e) {
		assertEquals('Unexpected error message - 05Jum2007',
			'Unknown name at position 2', e);
	}
	try {
		$.datepicker.parseDate('\'Day\' d of MM in the \'year\' yy',
			'Day 5 ov June in the year 2007');
		fail('Parsed invalid format - \'Day\' d of MM in the \'year\' yy');
	}
	catch (e) {
		assertEquals('Unexpected error message - Day 5 ov June in the year 2007',
			'Unexpected literal at position 7', e);
	}
	try {
		$.datepicker.parseDate('dd/mm/yy', '31/02/2007');
		fail('Parsed invalid date - dd/mm/yy');
	}
	catch (e) {
		assertEquals('Unexpected error message - 31/02/2007', 'Invalid date', e);
	}
	try {
		$.datepicker.parseDate('dd/mm/yy', 'not a date');
		fail('Parsed non-date string');
	}
	catch (e) {
		assertEquals('Unexpected error message - not a date',
			'Missing number at position 0', e);
	}
	try {
		$.datepicker.parseDate('dd/mm/yy', new Date(2007, 6 - 1, 5));
		fail('Parsed date object');
	}
	catch (e) {
		assertEquals('Unexpected error message - new Date()',
			'Missing number at position 0', e);
	}
	// other language
	try {
		$.datepicker.parseDate('DddMyy', 'dze05msi2007', 10,
			['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
			['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
			['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
			'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
			['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
			'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']);
		fail('Parsed invalid format - DddMyy (1)');
	}
	catch (e) {
		assertEquals('Unexpected error message - dze05msi2007',
			'Unknown name at position 0', e);
	}
	try {
		$.datepicker.parseDate('DddMyy', 'dth05mze2007', 10,
			['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
			['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
			['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
			'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
			['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
			'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']);
		fail('Parsed invalid format - DddMyy (2)');
	}
	catch (e) {
		assertEquals('Unexpected error message - dth05mze2007',
			'Unknown name at position 5', e);
	}
	try {
		$.datepicker.parseDate('DD dd MM yy', 'dzero 05 msix 2007', 10,
			['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
			['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
			['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
			'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
			['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
			'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']);
		fail('Parsed invalid format - DD dd MM yy (1)');
	}
	catch (e) {
		assertEquals('Unexpected error message - dzero 05 msix 2007',
			'Unknown name at position 0', e);
	}
	try {
		$.datepicker.parseDate('DD dd MM yy', 'dthree 05 mzero 2007', 10,
			['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
			['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
			['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
			'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
			['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
			'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']);
		fail('Parsed invalid format - DD dd MM yy (2)');
	}
	catch (e) {
		assertEquals('Unexpected error message - dthree 05 mzero 2007',
			'Unknown name at position 10', e);
	}
}

function testFormatDate() {
	var date = new Date(2007, 6 - 1, 5);
	assertEquals('Invalid formatted date - null', '',
		$.datepicker.formatDate('dd/mm/yy', null));
	assertEquals('Invalid formatted date - dd/mm/yy', '05/06/2007',
		$.datepicker.formatDate('dd/mm/yy', date));
	assertEquals('Invalid formatted date - d/m/y', '5/6/07',
		$.datepicker.formatDate('d/m/y', date));
	assertEquals('Invalid formatted date - yy-mm-dd', '2007-06-05',
		$.datepicker.formatDate('yy-mm-dd', date));
	assertEquals('Invalid formatted date - ddMyy', '05Jun2007',
		$.datepicker.formatDate('ddMyy', date));
	assertEquals('Invalid formatted date - DD, MM d, yy', 'Tuesday, June 5, 2007',
		$.datepicker.formatDate('DD, MM d, yy', date));
	assertEquals('Invalid formatted date - dd\'\'mm\'\'yy', '05\'06\'2007',
		$.datepicker.formatDate('dd\'\'mm\'\'yy', date));
	assertEquals('Invalid formatted date - \'Day\' d of MM in the \'year\' yy',
		'Day 5 of June in the year 2007',
		$.datepicker.formatDate('\'Day\' d of MM in the \'year\' yy', date));
	// other language
	assertEquals('Invalid formatted date - ddMyy', 'dth05msi2007',
		$.datepicker.formatDate('DddMyy', date,
		['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
		['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
		['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
		'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
		['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
		'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']));
	assertEquals('Invalid formatted date - DD dd MM yy', 'dthree 05 msix 2007',
		$.datepicker.formatDate('DD dd MM yy', date,
		['don', 'dtw', 'dth', 'dfo', 'dfi', 'dsi', 'dse'],
		['done', 'dtwo', 'dthree', 'dfour', 'dfive', 'dsix', 'dseven'],
		['mon', 'mtw', 'mth', 'mfo', 'mfi', 'msi',
		'mse', 'mei', 'mni', 'mte', 'mel', 'mtv'],
		['mone', 'mtwo', 'mthree', 'mfour', 'mfive', 'msix',
		'mdseven', 'meight', 'mnine', 'mten', 'meleven', 'mtwelve']));
}

function testGet() {
	assertEquals('Invalid default clearText', 'Clear', $.datepicker._defaults.clearText);
	assertEquals('Invalid instance clearText', 'Erase',
		$.datepicker._inst[0]._settings.clearText);
}

function testGetDefaultDate() {
	var inst = $.datepicker._inst[0];
	assertDateEquals('Invalid default date - today', new Date(), inst._getDefaultDate());
	// as date
	var date = new Date(2007, 6 - 1, 5);
	$('#dp').changeDatepicker({defaultDate: date});
	assertDateEquals('Invalid default date - 2007-06-05', date, inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: null});
	assertDateEquals('Invalid default date - reset', new Date(), inst._getDefaultDate());
	// as relative numeric offsets
	$('#dp').changeDatepicker({defaultDate: +7});
	assertDateEquals('Invalid default date - +7', offsetDate(7), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: -7});
	assertDateEquals('Invalid default date - -7', offsetDate(-7), inst._getDefaultDate());
	// as relative string offsets
	$('#dp').changeDatepicker({defaultDate: '1'});
	assertDateEquals('Invalid default date - 1', offsetDate(1), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '1d'});
	assertDateEquals('Invalid default date - 1d', offsetDate(1), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '+1  d'});
	assertDateEquals('Invalid default date - +1  d', offsetDate(1), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '-1 D'});
	assertDateEquals('Invalid default date - -1 D', offsetDate(-1), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '2w'});
	assertDateEquals('Invalid default date - 2w', offsetDate(14), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '+2  w'});
	assertDateEquals('Invalid default date - +2  w', offsetDate(14), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '-2 W'});
	assertDateEquals('Invalid default date - -2 W', offsetDate(-14), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '3m'});
	assertDateEquals('Invalid default date - 3m', offsetMonth(3), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '+3  m'});
	assertDateEquals('Invalid default date - +3  m', offsetMonth(3), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '-3 M'});
	assertDateEquals('Invalid default date - -3 M', offsetMonth(-3), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '4y'});
	assertDateEquals('Invalid default date - 4y', offsetMonth(48), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '+4  y'});
	assertDateEquals('Invalid default date - +4  y', offsetMonth(48), inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '-4 Y'});
	assertDateEquals('Invalid default date - -4 Y', offsetMonth(-48), inst._getDefaultDate());
	// as error offsets
	date = new Date();
	$('#dp').changeDatepicker({defaultDate: '2days'});
	assertDateEquals('Invalid default date - 2days', date, inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: 'now'});
	assertDateEquals('Invalid default date - now', date, inst._getDefaultDate());
	$('#dp').changeDatepicker({defaultDate: '2f'});
	assertDateEquals('Invalid default date - 2f', date, inst._getDefaultDate());
}

function testAdjustDate() {
	var adj = $('#adj');
	var inst = $.datepicker._inst[1];
	inst._rangeStart = null;
	adj.changeDatepicker({minDate: null, maxDate: null}).
		setDatepickerDate(new Date(2001, 2 - 1, 3));
	var adjusts = [[0, 'D', 2001, 2, 3], [1, 'D', 2001, 2, 4],
		[7, 'D', 2001, 2, 11], [-8, 'D', 2001, 2, 3],
		[-8, 'D', 2001, 1, 26], [+5, 'D', 2001, 1, 31],
		[0, 'M', 2001, 1, 31], [1, 'M', 2001, 2, 28],
		[13, 'M', 2002, 3, 28], [-3, 'M', 2001, 12, 28],
		[26, 'M', 2004, 2, 28], [1, 'D', 2004, 2, 29],
		[0, 'Y', 2004, 2, 29], [1, 'Y', 2005, 2, 28],
		[11, 'Y', 2016, 2, 28], [-12, 'Y', 2004, 2, 28]];
	for (var i = 0; i < adjusts.length; i++) {
		inst._adjustDate(adjusts[i][0], adjusts[i][1]);
		assertTrue('Invalid date adjustment ' + adjusts[i][0] + ' ' + adjusts[i][1],
			inst._selectedYear == adjusts[i][2] && inst._selectedMonth == (adjusts[i][3] - 1) &&
			inst._selectedDay == adjusts[i][4]);
	}
	// with minimum
	adj.changeDatepicker({minDate: new Date(2001, 1 - 1, 1)}).
		setDatepickerDate(new Date(2001, 2 - 1, 3));
	adjusts = [[0, 'D', 2001, 2, 3], [7, 'D', 2001, 2, 10],
		[-88, 'D', 2001, 1, 1], [5, 'D', 2001, 1, 6],
		[0, 'M', 2001, 1, 6], [13, 'M', 2002, 2, 6],
		[-20, 'M', 2001, 1, 1], [1, 'M', 2001, 2, 1],
		[0, 'Y', 2001, 2, 1], [6, 'Y', 2007, 2, 1],
		[-11, 'Y', 2001, 1, 1], [2, 'Y', 2003, 1, 1]];
	for (var i = 0; i < adjusts.length; i++) {
		inst._adjustDate(adjusts[i][0], adjusts[i][1]);
		assertTrue('Invalid date adjustment (min) ' + adjusts[i][0] + ' ' + adjusts[i][1],
			inst._selectedYear == adjusts[i][2] && inst._selectedMonth == (adjusts[i][3] - 1) &&
			inst._selectedDay == adjusts[i][4]);
	}
	// with maximum
	adj.changeDatepicker({minDate: null, maxDate: new Date(2001, 6 - 1, 30)}).
		setDatepickerDate(new Date(2001, 2 - 1, 3));
	adjusts = [[0, 'D', 2001, 2, 3], [7, 'D', 2001, 2, 10],
		[200, 'D', 2001, 6, 30], [-184, 'D', 2000, 12, 28],
		[0, 'M', 2000, 12, 28], [3, 'M', 2001, 3, 28],
		[6, 'M', 2001, 6, 30], [-5, 'M', 2001, 1, 30],
		[0, 'Y', 2001, 1, 30], [6, 'Y', 2001, 6, 30],
		[-11, 'Y', 1990, 6, 30], [2, 'Y', 1992, 6, 30]];
	for (var i = 0; i < adjusts.length; i++) {
		inst._adjustDate(adjusts[i][0], adjusts[i][1]);
		assertTrue('Invalid date adjustment (max) ' + adjusts[i][0] + ' ' + adjusts[i][1],
			inst._selectedYear == adjusts[i][2] && inst._selectedMonth == (adjusts[i][3] - 1) &&
			inst._selectedDay == adjusts[i][4]);
	}
}

function testGetNumberOfMonths() {
	var inst = $.datepicker._inst[0];
	assertArrayEquals('Invalid number of months (default)', [1, 1], inst._getNumberOfMonths());
	$('#dp').changeDatepicker({numberOfMonths: null});
	assertArrayEquals('Invalid number of months (null)', [1, 1], inst._getNumberOfMonths());
	$('#dp').changeDatepicker({numberOfMonths: 2});
	assertArrayEquals('Invalid number of months (2)', [1, 2], inst._getNumberOfMonths());
	$('#dp').changeDatepicker({numberOfMonths: [3, 4]});
	assertArrayEquals('Invalid number of months (3,4)', [3, 4], inst._getNumberOfMonths());
	$('#dp').changeDatepicker({numberOfMonths: 1});
}

function testGetMinMaxDate() {
	var inst = $.datepicker._inst[1];
	$('#adj').changeDatepicker({minDate: null, maxDate: null});
	assertNull('Invalid min date (null)', inst._getMinMaxDate('min'));
	assertNull('Invalid min date (null,false)', inst._getMinMaxDate('min', false));
	assertUndefined('Invalid min date (null,true)', inst._getMinMaxDate('min', true));
	assertNull('Invalid max date (null)', inst._getMinMaxDate('max'));
	var date = new Date();
	date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
	$('#adj').changeDatepicker({minDate: new Date()});
	assertDateEquals('Invalid min date', date, inst._getMinMaxDate('min'));
	assertDateEquals('Invalid min date (false)', date, inst._getMinMaxDate('min', false));
	assertDateEquals('Invalid min date (true)', date, inst._getMinMaxDate('min', true));
	inst._rangeStart = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 7);
	assertDateEquals('Invalid min date (range,false)', date, inst._getMinMaxDate('min', false));
	assertDateEquals('Invalid min date (range,true)', date, inst._getMinMaxDate('min', true));
	$('#adj').changeDatepicker({maxDate: new Date()});
	assertDateEquals('Invalid max date', date, inst._getMinMaxDate('max'));
	$('#adj').changeDatepicker({minDate: null});
	assertNull('Invalid min date (null,range,false)', inst._getMinMaxDate('min', false));
	assertDateEquals('Invalid min date (null,range,true)', inst._rangeStart, inst._getMinMaxDate('min', true));
	// as relative numeric offsets
	$('#adj').changeDatepicker({minDate: -7});
	assertDateEquals('Invalid min date (-7)', offsetDate(-7), inst._getMinMaxDate('min'));
	$('#adj').changeDatepicker({maxDate: +14});
	assertDateEquals('Invalid max date (+14)', offsetDate(14), inst._getMinMaxDate('max'));
	// as relative string offsets
	$('#adj').changeDatepicker({minDate: '3 w'});
	assertDateEquals('Invalid min date (3 w)', offsetDate(21), inst._getMinMaxDate('min'));
	$('#adj').changeDatepicker({maxDate: '2M'});
	assertDateEquals('Invalid max date (2M)', offsetMonth(2), inst._getMinMaxDate('max'));
	// as error offsets
	date = new Date();
	$('#adj').changeDatepicker({minDate: 'now'});
	assertDateEquals('Invalid min date (now)', date, inst._getMinMaxDate('min'));
	$('#adj').changeDatepicker({maxDate: '2f'});
	assertDateEquals('Invalid max date (2f)', date, inst._getMinMaxDate('max'));
}

function testGetFirstDayOfMonth() {
	var fd = [1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6];
	for (var m = 0; m < 12; m++) { 
		assertEquals('Invalid first day of month for ' + m,
			fd[m], $.datepicker._inst[0]._getFirstDayOfMonth(2007, m));
	}
}

function testGetDaysInMonth() {
	var md = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	for (var y = 2007; y < 2009; y++) {
		for (var m = 0; m < 12; m++) { 
			assertEquals('Invalid days in month for ' + m + '/' + y,
				(m == 1 ? (y == 2007 ? 28 : 29) : md[m]),
				$.datepicker._inst[0]._getDaysInMonth(y, m));
		}
	}
}

function offsetDate(offset) {
	var date = new Date();
	date.setDate(date.getDate() + offset);
	return date;
}

function offsetMonth(offset) {
	var date = new Date();
	date.setDate(Math.min(date.getDate(), $.datepicker._inst[0]._getDaysInMonth(
		date.getFullYear(), date.getMonth() + offset)));
	date.setMonth(date.getMonth() + offset);
	return date;
}

function assertDateEquals(msg, date1, date2) {
	assertTrue(msg + ' - null date', date1 != null && date2 != null);
	date1.setHours(0);
	date1.setMinutes(0);
	date1.setSeconds(0);
	date1.setMilliseconds(0);
	date2.setHours(0);
	date2.setMinutes(0);
	date2.setSeconds(0);
	date2.setMilliseconds(0);
	assertEquals(msg, date1.toString(), date2.toString());
}
</script>
</head>

<body>
<h1>UI Datepicker Tests</h1>

<p>This page contains <a href="http://www.jsunit.net/">JsUnit</a> tests for the UI Datepicker plugin.
	To see them, take a look at the source.</p>
<p><input type="text" id="dp"/></p>
<p><input type="text" id="adj"/></p>
<p><input type="text" id="rem"/></p>
</body>
</html>
